package com.tvunetworks.center.user.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.tvunetworks.center.common.model.dto.grid.AcceptedGrid;
import com.tvunetworks.center.common.model.dto.grid.GridResult;
import com.tvunetworks.center.common.model.param.GridStartLiveParam;
import com.tvunetworks.center.common.model.param.GridStopLiveParam;
import com.tvunetworks.center.common.util.JsonUtil;
import com.tvunetworks.center.common.util.Result;
import com.tvunetworks.center.common.util.ResultUtil;
import com.tvunetworks.center.user.model.param.GridAcceptedGridParam;
import com.tvunetworks.center.user.service.GridService;
import com.tvunetworks.center.user.util.AccessServerUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;

import static com.tvunetworks.center.common.constant.LocalConstant.API_HEADER_PARAM_KEY;

/**
 * @program:
 * @description:
 * @author HenryChen
 * @create: 5/21/2019 2:23 PM
 **/
@Service
@Slf4j
public class GridServiceImpl implements GridService {


    @Value("${gridmarket.acceptedGrid.url}")
    private String gridAcceptedGridAPi;

    @Value("${gridmarket.startLive.url}")
    private String gridStartLiveApi;

    @Value("${gridmarket.stopLive.url}")
    private String gridStopLiveApi;

    @Autowired
    private AccessServerUtil accessServerUtil;

    @Autowired
    @Qualifier("restTemplateApi")
    private RestTemplate restTemplate;

    @Override
    public List<AcceptedGrid> getGridByUserId(String userId, String condition) throws Exception {

        List<AcceptedGrid> result = null;

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add(API_HEADER_PARAM_KEY, accessServerUtil.generatorAccess());

        GridAcceptedGridParam param = new GridAcceptedGridParam()
                .setCondition(condition)
                .setUserId(userId);


        HttpEntity httpEntity = new HttpEntity(JsonUtil.toJsonStr(param), headers);
        ResponseEntity<GridResult> acceptedGridListEntity = null;
        try {
            acceptedGridListEntity = restTemplate.postForEntity(gridAcceptedGridAPi, httpEntity,
                    GridResult.class);
        } catch (RestClientException e) {
            log.error("Grid AcceptedGrid error userid [{}]", userId, e);
            return new ArrayList<>();
        }


        if (acceptedGridListEntity.getStatusCode() != HttpStatus.OK) {
            // 默认返回 0 个设备
            log.error("[{}] error, userId [{}] , data: [{}]", gridAcceptedGridAPi, userId, acceptedGridListEntity.toString());
            return new ArrayList<>();
        }


        GridResult gridResult = acceptedGridListEntity.getBody();

        if (gridResult == null) {
            log.error("AcceptedGrid api result is null,data: [{}]", acceptedGridListEntity.toString());
            return new ArrayList<>();
        }

        if (StringUtils.equals(gridResult.getErrorCode(), ResultUtil.SUCCESS)) {
            Object content = gridResult.getContent();

            if (content != null) {
                result = JsonUtil.convertValue(gridResult.getContent(), new TypeReference<List<AcceptedGrid>>() {
                });
            } else {
                log.error("AcceptedGrid [{}] no data , data: [{}]", gridAcceptedGridAPi, acceptedGridListEntity.toString());
            }
        } else {
            log.error("AcceptedGrid [{}] error , data: [{}]", gridAcceptedGridAPi, acceptedGridListEntity.toString());
        }

        if (CollectionUtils.isEmpty(result)) {
            result = new ArrayList<>();
        }

        if(log.isInfoEnabled()){
            log.info("user [{}], acceptedGrid size [{}]", userId, result.size());
        }

        return result;
    }

    @Override
    public Result gridStartLive(GridStartLiveParam param) throws Exception {

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add(API_HEADER_PARAM_KEY, accessServerUtil.generatorAccess());

        param.setRId(param.getRId().toLowerCase())
                .setXId(param.getXId().toLowerCase());

        HttpEntity httpEntity = new HttpEntity(JsonUtil.toJsonStr(param), headers);

        ResponseEntity<GridResult> startLiveResponseEntity;

        try {
            startLiveResponseEntity = restTemplate.postForEntity(gridStartLiveApi, httpEntity,
                    GridResult.class);
        } catch (RestClientException e) {
            log.error("Grid start live error R id [{}] xId [{}]", param.getRId(), param.getXId(), e);
            return ResultUtil.error("81001501", "Grid start live failed. reason :" + e.getMessage());
        }


        if (startLiveResponseEntity.getStatusCode() != HttpStatus.OK) {
            log.error(" Grid start live  [{}] error, userId: [{}] R id [{}], xId [{}], data: [{}]",
                    gridStartLiveApi,
                    param.getUserId(), param.getRId(), param.getXId(),
                    startLiveResponseEntity.toString());
            return ResultUtil.error("81001502", "Grid start live failed Grid response error http code :" + startLiveResponseEntity.getStatusCodeValue());
        }


        GridResult gridResult = startLiveResponseEntity.getBody();

        if (gridResult == null) {
            log.error("AcceptedGrid api result is null,data: [{}]", startLiveResponseEntity.toString());
            return ResultUtil.error("81001503", "Grid start live failed no message from Grid Server");
        }

        if (StringUtils.equals(gridResult.getErrorCode(), ResultUtil.SUCCESS)) {
            return ResultUtil.success();
        } else {
            log.error("Grid start live [{}] error , data: [{}]", gridStartLiveApi, startLiveResponseEntity.toString());
            return ResultUtil.error("81001504", "Grid start live failed Grid response error : " + gridResult.getErrorInfo());
        }
    }

    @Override
    public Result gridStopLive(GridStopLiveParam param) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add(API_HEADER_PARAM_KEY, accessServerUtil.generatorAccess());


        param.setRId(param.getRId().toLowerCase())
        .setXId(param.getXId().toLowerCase());

        HttpEntity httpEntity = new HttpEntity(JsonUtil.toJsonStr(param), headers);


        ResponseEntity<GridResult> stopLiveResponseEntity;
        try {
            stopLiveResponseEntity = restTemplate.postForEntity(gridStopLiveApi, httpEntity,
                    GridResult.class);
        } catch (RestClientException e) {
            log.error("Grid stop live error R id [{}] xId [{}]", param.getRId(), param.getXId(), e);
            return ResultUtil.error("81001601", "Grid stop live failed. reason :" + e.getMessage());
        }


        if (stopLiveResponseEntity.getStatusCode() != HttpStatus.OK) {
            log.error(" Grid start live  [{}] error, R id [{}], xId [{}], data: [{}]",
                    gridStartLiveApi,
                    param.getRId(), param.getXId(),
                    stopLiveResponseEntity.toString());
            return ResultUtil.error("81001502", "Grid start stop failed Grid response error http code :" + stopLiveResponseEntity.getStatusCodeValue());
        }


        GridResult gridResult = stopLiveResponseEntity.getBody();

        if (gridResult == null) {
            log.error("AcceptedGrid api result is null,data: [{}]", stopLiveResponseEntity.toString());
            return ResultUtil.error("81001503", "Grid start stop failed no message from Grid Server");
        }

        if (StringUtils.equals(gridResult.getErrorCode(), ResultUtil.SUCCESS)) {
            return ResultUtil.success();
        } else {
            log.error("Grid start live [{}] error , data: [{}]", gridStartLiveApi, stopLiveResponseEntity.toString());
            return ResultUtil.error("81001504", "Grid start stop failed Grid response error : " + gridResult.getErrorInfo());
        }

    }


}
